﻿# Créé par Pascal, le 07/02/2019 en Python 3.4

# !/usr/bin/env python3
# -*- coding: utf-8 -*-

#
# Dut Info Reims MATHS
#
# Module python pour les travaux pratiques de mathÃ©matiques
# en DUT Informatique de Reims
#
# "zerooo certified"
#

## ----------------------
## Graphes et algorithmes
## ----------------------

### Affichage de graphes, avec GraphViz

import numpy as np
from graphviz import Digraph, Graph
import matplotlib
import matplotlib.cm
# Fonction d'affichage d'un graphe Ã  partir d'une matrice d'adjacence
# M : matrice d'adjacence avec ou sans les poids (matrice numpy)
# directed : boolÃ©en indiquant si le graphe est orientÃ© ou non
# weighted : boolÃ©en indiquant si les arcs du graphe sont pondÃ©rÃ©s ou non
# label : si None les labels seront 0, 1, 2,..., n-1
# color : vecteur d'entiers contenant le numÃ©ro associÃ© Ã  la couleur
# title : nom du graphe
# view : boolÃ©en qui dÃ©termine l'ouverture d'une fenÃªtre de visualisation de l'image
# dispo : disposition des sommets. neato,circo, dot, fdp par exemple.
def display(M, directed = True, weighted = False, label = None, color = None, title = "G", view = False, dispo="neato"):
    # Nombre de sommets
    n = M.shape[0]
    # Labels des sommets
    if label == None:
        label = [str(i) for i in range(0, n)]
    # Couleur des sommets
    if color==None:
        lcol = [(1.,1.,1.,1.)]*n
    else:
        cm = matplotlib.cm.get_cmap('gist_rainbow')
        nbcol = max(color)
        lcol = [cm(1.*x/nbcol) if x!=0 else (1.,1.,1.,1.) for x in color]
    # Initialisation du graphe
    if directed == True:
        t = Digraph(title, engine = dispo, format = 'svg')
    else:
        t = Graph(title, engine = dispo, format = 'svg')
    # Attibuts graphiques
    t.attr('graph', overlap = 'false', fontsize = '16', label = title, bgcolor = "#ffffff00",fontcolor="grey")
    t.attr('node', shape = 'circle', fixedsize = 'true', width = '0.4', fontsize = '14', style = "filled", color = 'grey')
    t.attr('edge', arrowsize = '0.7', fontsize = '12',color="grey",fontcolor="grey")
    # Ajout des sommets
    for i in range(0,M.shape[0]):
        #t.attr('node', fillcolor = "%f, %f, %f, %f" % lcol[i])
        t.attr('node', fillcolor = matplotlib.colors.to_hex(lcol[i], keep_alpha=False))
        t.node(str(label[i]))
    # Ajout des arcs (dÃ©pend du type de matrice fournie : adjacence ou matrice de poids alacoutant)
    if weighted == False:
        for i in range(0,M.shape[0]):
            for j in range(0 if directed else i, M.shape[0]):
                if M[i,j]>0:
                    t.edge(str(label[i]),str(label[j]))
    else:
        for i in range(0,M.shape[0]):
            for j in range(0 if directed else i, M.shape[0]):
                if M[i,j]<float("inf"):
                    t.edge(str(label[i]),str(label[j]),label = str(M[i,j]))
    # Affichage
    if(view):
        t.view()
    else:
        t.render('output/'+title+'.gv', view=view)
    # Retour
    return(t)

# *** TESTS ***
#A = np.array([[1,1,2,0,1],[0,1,1,0,0],[1,0,1,1,4],[0,0,1,1,0]])
#couleurs = [1,2,3,4,2]
#display(A, weighted = True, color = couleurs)
# *** FIN ***


